package com.benefm.multipar.pad.util;

import android.util.Log;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtil {
    /**
     * bytes转换成十六进制字符串
     *
     * @param b byte数组
     * @return String 十六进制字符串
     */
    public static String byte2HexString(byte[] b) {
        String data = "";
        StringBuilder sb = new StringBuilder("");
        for (int n = 0; n < b.length; n++) {
            data = Integer.toHexString(b[n] & 0xFF);
            sb.append((data.length() == 1) ? "0" + data : data);
        }
        return sb.toString().trim();
    }

    public static String byteToMac(byte[] bytes) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < bytes.length; i++) {
            sb.append(String.format("%02X", bytes[i])).append(":");
        }
        return sb.substring(0, sb.length() - 1);
    }

    public static byte[] stringToBytes(String text) {
        int len = text.length();
        byte[] bytes = new byte[(len + 1) / 2];
        for (int i = 0; i < len; i += 2) {
            int size = Math.min(2, len - i);
            String sub = text.substring(i, i + size);
            bytes[i / 2] = (byte) Integer.parseInt(sub, 16);
        }
        return bytes;
    }

    public static String toHexString(byte[] bytes, String separator) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            int byteValue = 0xFF & b;
            if (byteValue < 0x10) {
                hexString.append("0").append(Integer.toHexString(0xFF & b)).append(separator);
            } else {
                hexString.append(Integer.toHexString(0xFF & b)).append(separator);
            }
        }
        return hexString.toString();
    }

    /**
     * byte数组转换为二进制字符串,每个字节以","隔开
     **/
    public static String byteArrToBinString(byte[] b, String separator) {
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            result.append(Long.toString(b[i] & 0xff, 2) + separator);
        }
        return result.toString().substring(0, result.length() - 1);
    }

    public static byte[] byteArrToBinArray(byte[] b, String separator) {
        byte[] b1 = new byte[b.length];
        for (int i = 0; i < b.length; i++) {
            b1[i] = Byte.parseByte(Long.toString(b[i] & 0xff, 2));
        }
        return b1;
    }

    public static byte[] intToByteArray(int i) {
        byte[] result = new byte[4];
        result[0] = (byte) ((i >> 24) & 0xFF);
        result[1] = (byte) ((i >> 16) & 0xFF);
        result[2] = (byte) ((i >> 8) & 0xFF);
        result[3] = (byte) (i & 0xFF);
        return result;
    }

    public static byte[] intToByteArray1(int i) {
        byte[] result = new byte[2];
        result[0] = (byte) ((i >> 8) & 0xFF);
        result[1] = (byte) (i & 0xFF);
        return result;
    }

    public static int byteArrayToInt(byte[] bytes) {
        int value = 0;
        // 由高位到低位
        for (int i = 0; i < 2; i++) {
            int shift = (2 - 1 - i) * 8;
            value += (bytes[i] & 0x00FF) << shift;// 往高位游
        }
        return value;
    }

    public static byte[] shortToByteArray(short i) {
        byte[] result = new byte[2];
        result[0] = (byte) ((i >> 8) & 0xFF);
        result[1] = (byte) (i & 0xFF);
        return result;
    }

    // 反转数据  小端在前
    public static byte[] reverse(byte[] arr) {
        byte[] arr1 = new byte[arr.length];
        for (int i = arr.length - 1; i >= 0; i--) {
            arr1[arr.length - i - 1] = arr[i];
        }
        return arr1;
    }

    public static byte[] hex2Bytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }

        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] bytes = new byte[length];
        String hexDigits = "0123456789abcdef";
        for (int i = 0; i < length; i++) {
            int pos = i * 2; // 两个字符对应一个byte
            int h = hexDigits.indexOf(hexChars[pos]) << 4; // 注1
            int l = hexDigits.indexOf(hexChars[pos + 1]); // 注2
            if (l == -1) { // 非16进制字符
                return null;
            }
            bytes[i] = (byte) (h | l);
        }
        return bytes;
    }


    public static ArrayList<String> splitDta(String args) {
        ArrayList<String> data_arr = new ArrayList<>();

        Pattern p = Pattern.compile("(.{3})");//这个3是指连续数字的最少个数
        Matcher m = p.matcher(args);
        while (m.find()) {
            int num = Integer.parseInt(m.group(), 16);
            data_arr.add(String.valueOf(num));
        }
        return data_arr;
    }

    public static List<String> convertData(String args) {
        List<String> data = new ArrayList<>();
        Pattern p = Pattern.compile("(.{3})");//这个3是指连续数字的最少个数
        Matcher m = p.matcher(args);
        while (m.find()) {
            data.add(m.group());
        }
        return data;
    }

    public static String convertEcgData(String args) {
        List<String> data = new ArrayList<>();
        Pattern p = Pattern.compile("(.{1})");//这个3是指连续数字的最少个数
        Matcher m = p.matcher(args);
        while (m.find()) {
            data.add(m.group());
        }
        String s = data.get(2) + data.get(0) + data.get(1);

        return s;
    }


    public static int[] changeNumber(byte[] data) {
        int[] onePackData = new int[data.length];
        for (int i = 0; i < data.length; i++) {
            onePackData[i] = (data[i] & 0xff);
        }
        return onePackData;
    }


    public static int[] concat(int[] a, int[] b) {
        int[] c = new int[a.length + b.length];
        System.arraycopy(a, 0, c, 0, a.length);
        System.arraycopy(b, 0, c, a.length, b.length);
        return c;
    }

    public static byte[] byteMerger(byte[] a, byte[] b) {
        byte[] c = new byte[a.length + b.length];
        System.arraycopy(a, 0, c, 0, a.length);
        System.arraycopy(b, 0, c, a.length, b.length);
        return c;
    }

    /**
     * byte转short
     *
     * @param data
     * @return
     */
    public static short[] byteToShort(byte[] data) {
        short[] shortValue = new short[data.length / 2];
        for (int i = 0; i < shortValue.length; i++) {
            shortValue[i] = (short) ((data[i * 2] & 0xff) | ((data[i * 2 + 1] & 0xff) << 8));
        }
        return shortValue;
    }

    /**
     * short转byte
     *
     * @param data
     * @return
     */
    public static byte[] shortToByte(short[] data) {
        byte[] byteValue = new byte[data.length * 2];
        for (int i = 0; i < data.length; i++) {
            byteValue[i * 2] = (byte) (data[i] & 0xff);
            byteValue[i * 2 + 1] = (byte) ((data[i] & 0xff00) >> 8);
        }
        return byteValue;
    }


    public static String formatFileSize(long size) {
        size = size * 1024 * 1024;
        DecimalFormat df = new DecimalFormat("#.0");
        String fileSizeString = "";
        if (size < 1024) {
            fileSizeString = df.format((double) size) + "B";
        } else if (size < 1048576) {
            fileSizeString = df.format((double) size / 1024) + "K";
        } else if (size < 1073741824) {
            fileSizeString = df.format((double) size / 1048576) + "M";
        } else {
            fileSizeString = df.format((double) size / 1073741824) + "G";
        }
        return fileSizeString;
    }


    public static String getMemorySize(long size) {
        size = size * 1024 * 1024;
        //如果字节数少于1024，则直接以B为单位，否则先除于1024，后3位因太少无意义
        if (size < 1024) {
            return size + "B";
        } else {
            size = size / 1024;
        }
        //如果原字节数除于1024之后，少于1024，则可以直接以KB作为单位
        //因为还没有到达要使用另一个单位的时候
        //接下去以此类推
        if (size < 1024) {
            return size + "KB";
        } else {
            size = size / 1024;
        }
        if (size < 1024) {
            //因为如果以MB为单位的话，要保留最后1位小数，
            //因此，把此数乘以100之后再取余
            size = size * 100;
            return size / 100 + "."
                    + size % 100 + "MB";
        } else {
            //否则如果要以GB为单位的，先除于1024再作同样的处理
            size = size * 100 / 1024;
            return size / 100 + "."
                    + size % 100 + "GB";
        }
    }

    public static byte getBitVale(byte b, int index) {
        if (index < 0 || index > 7) {
            Log.e("lsy", "Lead data IndexOutOfBoundsException==================================");
        }
        byte[] array = new byte[8];
        for (int i = 7; i >= 0; i--) {
            array[i] = (byte) (b & 1);
            b = (byte) (b >> 1);
        }
        return array[7 - index];
    }

    public static byte calculateXor(byte[] data) {
        int position = 2;
        byte result = data[position];
        for (int i = position + 1; i < data.length - 1; i++) {
            result = (byte) (result ^ data[i]);
        }
        return result;
    }


    public static Map<Integer, ArrayList<Float>> dataPackedConvert(int[] data, int TDNUM) {

        if (data == null) {
            return null;
        }
        if (data.length <= 1) {
            return null;
        }

        int[] onePackData = new int[data.length - 1];
        System.arraycopy(data, 0, onePackData, 0, data.length - 1);

        Map<Integer, ArrayList<Float>> maps = new LinkedHashMap<>();

        int leadCount = 8;//通道个数

        try {

            for (int i = 0; i < leadCount; i++) {
                maps.put(i, new ArrayList<>());
            }

            //当前数据要添加到哪个导联
            int leadIndex = 0;

            //当前数据解析后的值
            float value = 0;

            //数据体开始位置（除去数据头）
            int dataBegin = 5;


            //当前逻辑支持1,2,3,4通道；只需要修改TDNUM值即可
            int chushu = 3;//3为一个基本周期
            if (TDNUM == 4 || TDNUM == 3) {//不改以前逻辑
                chushu = 6;
            }

            for (int i = 0; i < onePackData.length; i++) {//数据总长
                int bt = onePackData[i + dataBegin];
                switch (i % chushu) {
                    case 0:
                        value = bt;

                        break;
                    case 1:
                        value = ((bt & 240) >> 4) * 256 + value;

                        value = value - 2048;
                        maps.get(0).add(value);

                        leadIndex++;
                        if (leadIndex % leadCount == 0) {
                            leadIndex = 0;
                        }

                        value = ((bt & 15)) * 256;


                        break;
                    case 2:
                        value = value + bt;
                        value = value - 2048;
                        if (TDNUM == 1) {
                            maps.get(0).add(value);
                        } else {
                            maps.get(1).add(value);
                        }


                        leadIndex++;
                        if (leadIndex % leadCount == 0) {
                            leadIndex = 0;
                        }
                        break;

                    //三个一个解析周期，后面的只是在重复
                    case 3:
                        value = bt;
                        break;
                    case 4:
                        value = ((bt & 240) >> 4) * 256 + value;
                        value = value - 2048;
                        maps.get(6).add(value);

                        value = ((bt & 15)) * 256;
                        break;
                    case 5:
                        value = value + bt;
                        value = value - 2048;

                        if (TDNUM == 3) {
                            maps.get(0).add(value);
                        } else {
                            maps.get(7).add(value);
                        }

                        break;
                }


            }
        } catch (Exception ignored) {
        }
        return maps;

    }

    public static Map<Integer, ArrayList<Short>> dataPackedConvert2(int[] data, int TDNUM) {

        if (data == null) {
            return null;
        }
        if (data.length <= 1) {
            return null;
        }

        int[] onePackData = new int[data.length - 1];
        System.arraycopy(data, 0, onePackData, 0, data.length - 1);

        Map<Integer, ArrayList<Short>> maps = new LinkedHashMap<>();

        int leadCount = 8;//通道个数

        try {

            for (int i = 0; i < leadCount; i++) {
                maps.put(i, new ArrayList<>());
            }

            //当前数据要添加到哪个导联
            int leadIndex = 0;

            //当前数据解析后的值
            short value = 0;

            //数据体开始位置（除去数据头）
            int dataBegin = 5;


            //当前逻辑支持1,2,3,4通道；只需要修改TDNUM值即可
            int chushu = 3;//3为一个基本周期
            if (TDNUM == 4 || TDNUM == 3) {//不改以前逻辑
                chushu = 6;
            }

            for (int i = 0; i < onePackData.length; i++) {//数据总长
                int bt = onePackData[i + dataBegin];
                switch (i % chushu) {
                    case 0:
                        value = (short) bt;

                        break;
                    case 1:
                        value = (short) (((bt & 240) >> 4) * 256 + value);

                        value = (short) (value - 2048);
                        maps.get(0).add(value);

                        leadIndex++;
                        if (leadIndex % leadCount == 0) {
                            leadIndex = 0;
                        }

                        value = (short) (((bt & 15)) * 256);


                        break;
                    case 2:
                        value = (short) (value + bt);
                        value = (short) (value - 2048);
                        if (TDNUM == 1) {
                            maps.get(0).add(value);
                        } else {
                            maps.get(1).add(value);
                        }


                        leadIndex++;
                        if (leadIndex % leadCount == 0) {
                            leadIndex = 0;
                        }
                        break;

                    //三个一个解析周期，后面的只是在重复
                    case 3:
                        value = (short) bt;
                        break;
                    case 4:
                        value = (short) (((bt & 240) >> 4) * 256 + value);
                        value = (short) (value - 2048);
                        maps.get(6).add(value);

                        value = (short) (((bt & 15)) * 256);
                        break;
                    case 5:
                        value = (short) (value + bt);
                        value = (short) (value - 2048);

                        if (TDNUM == 3) {
                            maps.get(0).add(value);
                        } else {
                            maps.get(7).add(value);
                        }

                        break;
                }


            }
        } catch (Exception ignored) {
        }
        return maps;
    }

}
